
#include "ENOilTankGroupHeatFluxUserObject.h"
#include "FEProblem.h"
#include "libmesh/elem.h"
#include "libmesh/fe.h"
#include "libmesh/string_to_enum.h"
#include "libmesh/quadrature_gauss.h"
#include "libmesh/plane.h"
#include "MooseMesh.h"
#include <fstream>
#include <time.h>
#include "RayLine.h"
#include "MooseRandom.h"

//#include "MemData.h"
using namespace std;

registerMooseObject("RoshanApp", ENOilTankGroupHeatFluxUserObject);
template<>
InputParameters validParams<ENOilTankGroupHeatFluxUserObject>()
{
	InputParameters params = validParams<SideUserObject>();
	params += validParams<RandomInterface>();
	params.addCoupledVar("temperature", "temperature");
	params.addRequiredParam< string >("boundary_groups", "The list of boundary groups");
	params.addRequiredParam< int >("n_oil_tank", "number of oil tank in this oil tank group");
	params.addRequiredParam< bool >("write_or_read", "compute oil tank mesh or not");
	params.addRequiredParam< vector<string> >("oil_tank_mesh_file_list", "oil tank mesh file list of this group");
	params.addRequiredParam< vector<Real> >("oil_volume_list", "oil volume of oil tank group");
	params.addRequiredParam< vector<Real> >("oil_temperature_list", "oil temperature of oil tank group");
	params.addRequiredParam< string >("oil_supply_list_file", "oil supply along time");
	params.addRequiredParam< string >("gravity_list_file", "gravity along time");
	params.addRequiredParam< string >("oil_material_property_file", "file of oil material property");
	params.addRequiredParam< string >("gas_material_property_file", "file of gas material property");
	params.addParam< int >("iteration_nt", 10, "devide of dt for sovling oil tank");
	
	return params;
}

ENOilTankGroupHeatFluxUserObject::ENOilTankGroupHeatFluxUserObject(const InputParameters & parameters) :
	SideUserObject(parameters),
	RandomInterface(parameters, *parameters.get<FEProblem *>("_fe_problem"), parameters.get<THREAD_ID>("_tid"), false),
	_problem_ptr(getParam<FEProblemBase*>("_fe_problem_base")),
	_time(_problem_ptr->time()),
	_t_step(_problem_ptr->timeStep()),
	_dt(_problem_ptr->dt()),
	_temperature(coupledValue("temperature")),
    _n_oil_tank(getParam< int >("n_oil_tank")),
    _write_or_read(getParam< bool >("write_or_read")),
    _oil_tank_mesh_file_list(getParam< vector<string> >("oil_tank_mesh_file_list")),
    _oil_volume_list(getParam< vector<Real> >("oil_volume_list")),
    _oil_temperature_list(getParam< vector<Real> >("oil_temperature_list")),
	_iteration_nt(getParam< int >("iteration_nt"))
{
	string oil_supply_list_file = getParam<string>("oil_supply_list_file");
	string gravity_list_file = getParam<string>("gravity_list_file");
	string oil_material_property_file = getParam<string>("oil_material_property_file");
	string gas_material_property_file = getParam<string>("gas_material_property_file");
	set_oil_supply(oil_supply_list_file);
	set_gravity_list(gravity_list_file);
	set_oil_gas_property(oil_material_property_file, _oil_material_property);
	set_oil_gas_property(gas_material_property_file, _gas_material_property);

	for (unsigned int i = 0; i < _n_oil_tank; ++i)
	{
		ENOilTank oiltank_temp = ENOilTank();
		_tank_group.push_back(oiltank_temp);
	}
}

ENOilTankGroupHeatFluxUserObject::~ENOilTankGroupHeatFluxUserObject()
{
	for(unsigned int i = 0; i < _all_element.size(); i++)
	{
		delete _all_element[i];
	}
}

void ENOilTankGroupHeatFluxUserObject::initialSetup()
{
	string boundary_groups = getParam<string>("boundary_groups");
	vector<BoundaryName> group;
	vector< vector<BoundaryName> > group_set;
	MooseUtils::tokenize<BoundaryName>(boundary_groups, group, 1, ",");
	group_set.resize(group.size());
	for(unsigned int i = 0; i < group.size(); ++i)
	{
		MooseUtils::tokenize<BoundaryName>(group[i], group_set[i], 1, " ");
	}

	for(unsigned int i = 0; i < group.size(); ++i)
	{
		cout << "boundary_group_" << i << ": " << group[i] << endl;
	}

	cout << endl << "Mesh modifying..." << endl;

	vector<BoundaryName> boundary = getParam<std::vector<BoundaryName> >("boundary");
	std::set<BoundaryID> boundary_ids;
	for(vector<BoundaryName>::iterator it = boundary.begin(); it != boundary.end(); ++it)
	{
		BoundaryID id = _mesh.getBoundaryID(*it);
		boundary_ids.insert(id);
	}

	MeshBase & mesh = _mesh.getMesh();
	const BoundaryInfo &bnd_info = mesh.get_boundary_info();

	MeshBase::const_element_iterator el = mesh.active_elements_begin();
	const MeshBase::const_element_iterator end_el = mesh.active_elements_end();
	for ( ; el != end_el ; ++el)
	{
		const Elem *elem = *el;

		for (unsigned int side=0; side < elem->n_sides(); ++side)
		{
			if (elem->neighbor_ptr(side))
					continue;

			const Elem *elem_side = elem->build_side_ptr(side).release();
			vector<boundary_id_type> bnd_id_vec;
			bnd_info.boundary_ids(elem, side, bnd_id_vec);
			int bnd_id = bnd_id_vec[0];

			int bnd_in_which_group =-1;
			for(unsigned int i = 0; i < group.size(); ++i)
			{
				for(unsigned int j = 0; j < group_set[i].size(); ++j)
				{
					if(_mesh.getBoundaryID(group_set[i][j]) == bnd_id)
					{
						bnd_in_which_group = i;
						break;
					}
				}
			}

			if(find(boundary_ids.begin(), boundary_ids.end(), bnd_id) == boundary_ids.end())
			{
				delete elem_side;
				continue;
			}

			unsigned int dim = _mesh.dimension();
			FEType fe_type(Utility::string_to_enum<Order>("CONSTANT"), Utility::string_to_enum<FEFamily>("MONOMIAL"));
			FEBase* _fe_face = (FEBase::build(dim, fe_type)).release();
			QGauss* _qface = new QGauss(dim - 1, FIRST);
			_fe_face->attach_quadrature_rule(_qface);
			_fe_face->reinit(elem, side);
			const std::vector<Point> normals = _fe_face->get_normals();
			_all_element.push_back(elem_side);
			_all_element_normal.push_back(normals[0]);
			_all_element_id.push_back(bnd_in_which_group);
			delete _fe_face;
			delete _qface;
		}
	}

	for (unsigned int i = 0; i < _all_element.size(); i++)
	{
		_center_point_list.push_back(_all_element[i]->centroid());
	}

	_temperature_bar.resize(_all_element.size(), 0.0);
	_oil_tank_heat_flux.resize(_all_element.size(), 0.0);
	_oil_tank_heat_flux_jacobi.resize(_all_element.size(), 0.0);

	_communicator.barrier();
	set_side_mesh();
	update_side_T_list();
	_communicator.barrier();

	cout << "Mesh modify completed" << endl;
	cout << endl << "Count of boundary element: " << _all_element.size() << endl << endl;

	clock_t start_time,end_time;
	start_time = clock();

	if (_write_or_read)
	{
		_communicator.barrier();

		compute_tank_mesh(_oil_tank_mesh_file_list);
		
		if (processor_id() == 0)
		{
			cout << "Writing......" << endl;
			write_tank_mesh_to_file(_oil_tank_mesh_file_list);
			cout << "Write completed" << endl;
		}

		_communicator.barrier();
	}

	else
	{
		_communicator.barrier();

		cout << endl;
		cout << "Reading......" << endl;
		set_tank_mesh(_oil_tank_mesh_file_list);
		cout << "Read completed" << endl;
		_communicator.barrier();
	}

	for (unsigned int i = 0; i < _tank_group.size(); ++i)
	{
		Point gravity = get_gravity(0.0);
		_tank_group[i].set(_oil_tank_elem_point_list[i],
			_oil_tank_elem_volume_list[i],
			_oil_tank_side_point_list[i],
			_oil_tank_side_area_list[i],
			_oil_tank_side_T_list[i],
			_oil_material_property,
			_gas_material_property,
			gravity,
			_oil_volume_list[i],
			_oil_temperature_list[i]);
	}

	cout << "_tank_group_size: " << _tank_group.size() << endl;

	end_time = clock();
	cout << endl;
	cout << "time: " << end_time - start_time << endl;
}

void ENOilTankGroupHeatFluxUserObject::initialize()
{
}

void ENOilTankGroupHeatFluxUserObject::execute()
{
	int findi = Find_i(_current_side_elem);
	Real temp_bar(0);

	for(unsigned int _qp = 0; _qp < _q_point.size(); ++_qp)
	{
		temp_bar += (_JxW[_qp] * _temperature[_qp]);
	}

	temp_bar /= _current_side_volume;
	_temperature_bar[findi] = temp_bar;
}

void ENOilTankGroupHeatFluxUserObject::finalize()
{
	{
		_communicator.sum<Real>(_temperature_bar);
	}

	for(int i = 0; i < _all_element.size(); i++)
	{
		_oil_tank_heat_flux[i] = 0;
		_oil_tank_heat_flux_jacobi[i] = 0;
	}

	update_side_T_list();
	solve_tank_group();
	computeHeatFlux();

	{
		_communicator.sum<Real>(_oil_tank_heat_flux);
		_communicator.sum<Real>(_oil_tank_heat_flux_jacobi);
	}

	for(int i = 0; i < _all_element.size(); i++)
	{
		_temperature_bar[i] = 0;
	}
}

void ENOilTankGroupHeatFluxUserObject::computeHeatFlux()
{
	int local_begin, local_end, local_n;
	int quotient = _all_element.size() / n_processors();
	int remainder = _all_element.size() % n_processors();
	if (processor_id() < remainder)
	{
		local_n = quotient + 1;
		local_begin = processor_id() * local_n;
		local_end = local_begin + local_n;
	}
	else
	{
		local_n = quotient;
		local_begin = processor_id() * local_n + remainder;
		local_end = local_begin + local_n;
	}

	for (int i = local_begin; i < local_end; i++)
	{
		int side_id_temp = _all_element_id[i];
		for (unsigned int j = 0; j < _oil_tank_side_point_list[side_id_temp].size(); ++j)
		{
			if ((_all_element[i]->centroid() - _oil_tank_side_point_list[side_id_temp][j]).norm() < ENOilTankuZero)
			{
				_oil_tank_heat_flux[i] = _heat_flux_list[side_id_temp][j];
				_oil_tank_heat_flux_jacobi[i] = 0.0;
				break;
			}
		}
	}

	//for (unsigned int i = 0; i < _all_element.size(); ++i)
	//{
	//	int side_id_temp = _all_element_id[i];
	//	for (unsigned int j = 0; j < _oil_tank_side_point_list[side_id_temp].size(); ++j)
	//	{
	//		if ((_all_element[i]->centroid() - _oil_tank_side_point_list[side_id_temp][j]).norm() < ENOilTankuZero)
	//		{
	//			_oil_tank_heat_flux[i] = _heat_flux_list[side_id_temp][j];
	//			_oil_tank_heat_flux_jacobi[i] = 0.0;
	//			break;
	//		}
	//	}
	//}
}

int ENOilTankGroupHeatFluxUserObject::Find_i(const Elem * elem) const
{
	int findi = -1;

	for (unsigned int i = 0; i < _all_element.size(); i++)
	{
		if( (_all_element[i]->centroid() - elem->centroid()).norm() < 1e-10 )
		{
			findi = i;
			break;
		}
	}

	if(findi != -1)
		return findi;
	mooseError("Cannot find i.");
}

void ENOilTankGroupHeatFluxUserObject::solve_tank_group()
{
	vector< vector<Real> > HF_group_temp;
	vector<Real> T_temp = _oil_temperature_list;
	Point gravity = get_gravity(_time);
	Real oil_consume = _dt * get_oil_consume_rate(_time);
	update_oilvolume_T(oil_consume);
	cout << "Oil volume: ";
	for (unsigned int j = 0; j < _tank_group.size(); ++j)
	{
		cout << _oil_volume_list[j] << "	";
	}
	cout << endl;

	for (unsigned int j = 0; j < _tank_group.size(); ++j)
	{
		_tank_group[j].update_gravity(gravity);
		_tank_group[j].update_side_temperature(_oil_tank_side_T_list[j]);
		_tank_group[j].solve_oil_tank(_dt, _iteration_nt);
		T_temp[j] = _tank_group[j]._oil_temperature;
		vector<Real> HF_temp = _tank_group[j]._side_heatflux;
		HF_group_temp.push_back(HF_temp);
	}
	_oil_temperature_list = T_temp;
	_heat_flux_list = HF_group_temp;

	cout << "Oil Temperature: ";
	for (unsigned int j = 0; j < _tank_group.size(); ++j)
	{
		cout << _oil_temperature_list[j] << "	";
	}
	cout << endl;
}

void ENOilTankGroupHeatFluxUserObject::compute_tank_mesh(vector<string> oil_tank_mesh_file_list)
{

}

void ENOilTankGroupHeatFluxUserObject::write_tank_mesh_to_file(vector<string> oil_tank_mesh_file_list)
{

}

void ENOilTankGroupHeatFluxUserObject::set_tank_mesh(vector<string> oil_tank_mesh_file_list)
{
	for (unsigned int i = 0; i < _tank_group.size(); ++i)
	{
		vector<Point> elem_point_temp;
		vector<Real> elem_volume_temp;

		ifstream tank_mesh_read(oil_tank_mesh_file_list[i].c_str());
		if (!tank_mesh_read.good())
		{
			mooseError("Read tank mesh filename " + oil_tank_mesh_file_list[i] + " failed!");
		}

		string line;
		getline(tank_mesh_read, line);
		istringstream iss(line);
		int f;
		vector<int> head;
		while (iss >> f)
			head.push_back(f);

		unsigned int line_of_tank_mesh = head[0];
		if (line_of_tank_mesh < 1)
		{
			tank_mesh_read.close();
			mooseError("Elem of tank mesh is less than 1! Please check " + oil_tank_mesh_file_list[i] + "!");
		}

		for (unsigned int j = 0; j < line_of_tank_mesh; ++j)
		{
			int k = 0;
			Real d = 0.0;
			getline(tank_mesh_read, line);
			istringstream transline(line);

			vector<Real> para;
			while (transline >> d)
			{
				para.push_back(d);
				k += 1;
			}

			if (k != 4)
			{
				tank_mesh_read.close();
				mooseError("Number of tank mesh does not equal 4! Please check " + oil_tank_mesh_file_list[i] + "!");
			}
			elem_point_temp.push_back(Point(para[0], para[1], para[2]));
			elem_volume_temp.push_back(para[3]);
		}
		tank_mesh_read.close();

		_oil_tank_elem_point_list.push_back(elem_point_temp);
		_oil_tank_elem_volume_list.push_back(elem_volume_temp);
	}
}

void ENOilTankGroupHeatFluxUserObject::set_side_mesh()
{
	for (unsigned int i = 0; i < _tank_group.size(); ++i)
	{
		vector<Point> side_point_temp;
		vector<Real> side_area_temp;

		for (unsigned int j = 0; j < _all_element.size(); ++j)
		{
			if (_all_element_id[j] == i)
			{
				side_point_temp.push_back(_all_element[j]->centroid());
				side_area_temp.push_back(_all_element[j]->volume());
			}
		}
		_oil_tank_side_point_list.push_back(side_point_temp);
		_oil_tank_side_area_list.push_back(side_area_temp);
	}
}

void ENOilTankGroupHeatFluxUserObject::set_oil_supply(string oil_supply_filename)
{
	_oil_supply_list.clear();

	ifstream supply_read(oil_supply_filename.c_str());
	if (!supply_read.good())
	{
		mooseError("Read oil supply filename " + oil_supply_filename + " failed!");
	}

	string line;
	getline(supply_read, line);
	istringstream iss(line);
	int f;
	vector<int> head;
	while (iss >> f)
		head.push_back(f);

	unsigned int line_of_supply = head[0];

	if (line_of_supply < 1)
	{
		supply_read.close();
		mooseError("Line of oil supply is less than 1! Please check " + oil_supply_filename + "!");
	}

	for (unsigned int i = 0; i < line_of_supply; ++i)
	{
		int k = 0;
		Real d = 0.0;
		getline(supply_read, line);
		istringstream transline(line);

		vector<Real> para;
		while (transline >> d)
		{
			para.push_back(d);
			k += 1;
		}

		if (k != 2)
		{
			supply_read.close();
			mooseError("Number of oil supply does not equal 2! Please check " + oil_supply_filename + "!");
		}

		_oil_supply_list.push_back(para);
	}

	if (_oil_supply_list.size() < 1)
	{
		for (unsigned int i = 0; i < _oil_supply_list.size() - 1; ++i)
		{
			if (_oil_supply_list[i + 1][0] <= _oil_supply_list[i][0])
			{
				supply_read.close();
				mooseError("In the oil supply file " + oil_supply_filename + ", the time is not increasing! Please check it!");
			}
		}
	}

	supply_read.close();
}

void ENOilTankGroupHeatFluxUserObject::set_gravity_list(string gravity_list_filename)
{
	_gravity_list.clear();

	ifstream gravity_read(gravity_list_filename.c_str());
	if (!gravity_read.good())
	{
		mooseError("Read gravity filename " + gravity_list_filename + " failed!");
	}

	string line;
	getline(gravity_read, line);
	istringstream iss(line);
	int f;
	vector<int> head;
	while (iss >> f)
		head.push_back(f);

	unsigned int line_of_gravity = head[0];

	if (line_of_gravity < 1)
	{
		gravity_read.close();
		mooseError("Line of gravity is less than 1! Please check " + gravity_list_filename + "!");
	}

	for (unsigned int i = 0; i < line_of_gravity; ++i)
	{
		int k = 0;
		Real d = 0.0;
		getline(gravity_read, line);
		istringstream transline(line);

		vector<Real> para;
		while (transline >> d)
		{
			para.push_back(d);
			k += 1;
		}

		if (k != 4)
		{
			gravity_read.close();
			mooseError("Number of gravity does not equal 4! Please check " + gravity_list_filename + "!");
		}
		_gravity_list.push_back(para);
	}

	if (_gravity_list.size() > 1)
	{
		for (unsigned int i = 0; i < _gravity_list.size() - 1; ++i)
		{
			if (_gravity_list[i + 1][0] <= _gravity_list[i][0])
			{
				gravity_read.close();
				mooseError("In the gravity list file " + gravity_list_filename + ", the time is not increasing! Please check it!");
			}
		}
	}

	gravity_read.close();
}

void ENOilTankGroupHeatFluxUserObject::set_oil_gas_property(string property_filename, vector< vector<Real> >& material_property)
{
	material_property.clear();

	ifstream property_read(property_filename.c_str());
	if (!property_read.good())
	{
		mooseError("Read property filename " + property_filename + " failed!");
	}

	string line;
	getline(property_read, line);
	istringstream iss(line);
	int f;
	vector<int> head;
	while (iss >> f)
		head.push_back(f);

	unsigned int line_of_property = head[0];

	if (line_of_property < 1)
	{
		property_read.close();
		mooseError("Line of property is less than 1! Please check " + property_filename + "!");
	}

	for (unsigned int i = 0; i < line_of_property; ++i)
	{
		int k = 0;
		Real d = 0.0;
		getline(property_read, line);
		istringstream transline(line);

		vector<Real> para;
		while (transline >> d)
		{
			para.push_back(d);
			k += 1;
		}

		if (k != 6)
		{
			property_read.close();
			mooseError("Number of property does not equal 6! Please check " + property_filename + "!");
		}

		material_property.push_back(para);
	}

	if (material_property.size() > 1)
	{
		for (unsigned int i = 0; i < material_property.size() - 1; ++i)
		{
			if (material_property[i + 1][0] <= material_property[i][0])
			{
				property_read.close();
				mooseError("In the materal file " + property_filename + ", the temperature is not increasing!! Please check it!");
			}
		}
	}

	property_read.close();
}

void ENOilTankGroupHeatFluxUserObject::update_side_T_list()
{
	_oil_tank_side_T_list.clear();

	for (unsigned int i = 0; i < _tank_group.size(); ++i)
	{
		vector<Real> side_T_temp;

		for (unsigned int j = 0; j < _all_element.size(); ++j)
		{
			if (_all_element_id[j] == i)
			{
				side_T_temp.push_back(_temperature_bar[j]);
			}
		}
		_oil_tank_side_T_list.push_back(side_T_temp);
	}
}

void ENOilTankGroupHeatFluxUserObject::update_oilvolume_T(Real oil_consume)
{
	Real T_temp = 0.0;//来自上一个邮箱的油温
	Real M_temp = 0.0;//来自上一个邮箱的质量
	Real density_cur = 1.0;

	Real den_temp = 1.0;
	Real cap_temp = 1.0;
	Real con_temp = 1.0;
	Real vis_temp = 1.0;
	Real exp_temp = 1.0;

	for (unsigned int i = 0; i < _tank_group.size(); ++i)
	{
		if (_tank_group[i]._is_empty == true)
		{
			continue;
		}
		else
		{
			_tank_group[i].get_property(_tank_group[i]._oil_temperature, den_temp, cap_temp, con_temp, vis_temp, exp_temp, "OIL");
			density_cur = den_temp;
			Real oil_M_0 = _tank_group[i]._oil_volume * density_cur + M_temp;
			if (oil_M_0 / density_cur <= ENOilTankuZero)
			{
				continue;
			}
			else
			{
				T_temp = (M_temp * T_temp + _tank_group[i]._oil_volume * density_cur * _tank_group[i]._oil_temperature) / oil_M_0;
				_tank_group[i].get_property(T_temp, den_temp, cap_temp, con_temp, vis_temp, exp_temp, "OIL");
				density_cur = den_temp;
				Real oil_M_1 = oil_M_0 - oil_consume;
				if (oil_M_1 < 0.0)
				{
					_tank_group[i].update_oil_volume(0.0);
					_tank_group[i].update_oil_temperature(T_temp);
					M_temp = -oil_M_1;
					_oil_volume_list[i] = 0.0;
				}
				else
				{
					_tank_group[i].update_oil_volume(oil_M_1 / density_cur);
					_tank_group[i].update_oil_temperature(T_temp);
					M_temp = oil_consume;
					_oil_volume_list[i] = oil_M_1 / density_cur;
				}
			}
		}
	}
}

Real ENOilTankGroupHeatFluxUserObject::get_oil_consume_rate(Real time)
{
	Real oil_consume_rate = 0.0;

	if (time <= _oil_supply_list[0][0])
	{
		oil_consume_rate = _oil_supply_list[0][1];
		return oil_consume_rate;
	}
	else if (time > _oil_supply_list[_oil_supply_list.size() - 1][0])
	{
		oil_consume_rate = _oil_supply_list[_oil_supply_list.size() - 1][1];
		return oil_consume_rate;
	}
	else
	{
		for (unsigned int i = 1; i < _oil_supply_list.size(); ++i)
		{
			if (time <= _oil_supply_list[i][0])
			{
				Real weight_temp = 0.0;
				if (abs(_oil_supply_list[i][0] - _oil_supply_list[i - 1][0]) < ENOilTankuZero)
				{
					weight_temp = 0.0;
				}
				else
				{
					weight_temp = (time - _oil_supply_list[i - 1][0]) / (_oil_supply_list[i][0] - _oil_supply_list[i - 1][0]);
				}
				oil_consume_rate = weight_temp * _oil_supply_list[i - 1][1] + (1.0 - weight_temp) * _oil_supply_list[i][1];
				return oil_consume_rate;
				break;
			}
			else
			{
				continue;
			}
		}
		return 0.0;
	}
}

Point ENOilTankGroupHeatFluxUserObject::get_gravity(Real time)
{
	Point gravity;

	if (time <= _gravity_list[0][0])
	{
		gravity = Point(_gravity_list[0][1], _gravity_list[0][2], _gravity_list[0][3]);
		if (gravity.norm() < 10.0 * ENOilTankuZero)
		{
			gravity = Point(0.0, 0.0, 10.0 * ENOilTankuZero);
		}
		return gravity;
	}
	else if (time > _gravity_list[_gravity_list.size() - 1][0])
	{
		gravity = Point(_gravity_list[_gravity_list.size() - 1][1], _gravity_list[_gravity_list.size() - 1][2], _gravity_list[_gravity_list.size() - 1][3]);
		if (gravity.norm() < 10.0 * ENOilTankuZero)
		{
			gravity = Point(0.0, 0.0, 10.0 * ENOilTankuZero);
		}
		return gravity;
	}
	else
	{
		for (unsigned int i = 1; i < _gravity_list.size(); ++i)
		{
			if (time <= _gravity_list[i][0])
			{
				Real weight_temp = 0.0;
				if (abs(_gravity_list[i][0] - _gravity_list[i - 1][0]) < ENOilTankuZero)
				{
					weight_temp = 0.0;
				}
				else
				{
					weight_temp = (time - _gravity_list[i - 1][0]) / (_gravity_list[i][0] - _gravity_list[i - 1][0]);
				}
				Point P0_temp = Point(_gravity_list[i - 1][1], _gravity_list[i - 1][2], _gravity_list[i - 1][3]);
				Point P1_temp = Point(_gravity_list[i][1], _gravity_list[i][2], _gravity_list[i][3]);
				gravity = P0_temp * weight_temp + P1_temp * (1.0 - weight_temp);
				if (gravity.norm() < 10.0 * ENOilTankuZero)
				{
					gravity = Point(0.0, 0.0, 10.0 * ENOilTankuZero);
				}
				return gravity;
				break;
			}
			else
			{
				continue;
			}
		}
		return Point(0.0, 0.0, 10.0 * ENOilTankuZero);
	}
}

void ENOilTankGroupHeatFluxUserObject::print_flux_to_file()
{
	string _filename = "flux.dat";
	Point p = Point(0.0, 0.0, 0.0);

	ofstream rd_write;
	rd_write.open(_filename.c_str(), ios::trunc);
	if(!rd_write.is_open())
		mooseError("Error opening file '" + _filename + "' fail.");

	rd_write << _all_element.size() << endl;
	for(unsigned int i = 0; i < _all_element.size(); i++)
	{
		p = _all_element[i]->centroid();
		rd_write << p(0) << '	' << p(1) << '	' << p(2) << '	' << _oil_tank_heat_flux[i] << endl;
	}

	rd_write.close();
}
